package com.k.base.jdk.thread;

import java.util.concurrent.*;

/**
 * @author kivil
 */
public class ThreadUtils {
    private static ThreadPoolExecutor threadPool;
    private static final int DEFAULT_CORE_POOL_SIZE = 5;
    private static final int DEFAULT_MAXIMUM_POOL_SIZE = 10;
    private static final long DEFAULT_KEEP_ALIVE_TIME = 60;
    private static final TimeUnit DEFAULT_UNIT = TimeUnit.SECONDS;

    /**
     * 创建线程
     *
     * @param corePoolSize    核心线程
     * @param maximumPoolSize 最大线程
     * @param keepAliveTime   10(maximumPoolSize) -5(corePoolSize) = 5(新建的线程) 这 5个新建的线程 ,空闲时间(keepAliveTime),退出。
     * @param unit            keepAliveTime's Unit
     * @param workQueue       LinkedBlockingQueue
     * @param threadFactory   ThreadFactoryBuilder
     * @param handler         RejectedExecutionHandler
     * @return ExecutorService
     */
    public static ThreadPoolExecutor getThreadPoolE(int corePoolSize,
                                                    int maximumPoolSize,
                                                    long keepAliveTime,
                                                    TimeUnit unit,
                                                    BlockingQueue<Runnable> workQueue,
                                                    ThreadFactory threadFactory,
                                                    RejectedExecutionHandler handler) {
        return new ThreadPoolExecutor(
                // 核心线程
                corePoolSize,
                // 最大线程
                maximumPoolSize,
                // 10(maximumPoolSize) -5(corePoolSize) = 5(新建的线程) 这 5个新建的线程 ,空闲时间(keepAliveTime),退出。
                keepAliveTime, unit,
                workQueue,
                threadFactory,
                handler
        );
    }

    private static ThreadPoolExecutor getThreadPoolDefault() {
        return new ThreadPoolExecutor(
                DEFAULT_CORE_POOL_SIZE,
                DEFAULT_MAXIMUM_POOL_SIZE,
                DEFAULT_KEEP_ALIVE_TIME, DEFAULT_UNIT,
                new LinkedBlockingQueue<>(32),
                new ThreadPoolExecutor.AbortPolicy()
        );
    }

    private static ExecutorService getThreadPoolCache() {
        if (threadPool == null) {
            threadPool = getThreadPoolDefault();
            return threadPool;
        }else{
            if (!threadPool.isShutdown() && !threadPool.isTerminated() && !threadPool.isTerminating()) {
                threadPool = getThreadPoolDefault();
                return threadPool;
            }
        }
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return getThreadPoolCache();
    }

    public static ExecutorService getThreadPool() {
        return getThreadPoolDefault();
    }

    public static void main(String[] args) {
        ExecutorService executorService = getThreadPool();
        // do something
        executorService.shutdown();
    }
}
